package com.hdsx.abatis.dao.db;

/***********************************************************************
 * Module:  DefaultSqlHelper.java
 * Author:  kemi
 * Purpose: Defines the Class DefaultSqlHelper
 ***********************************************************************/

import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import jsqlite.Stmt;
import android.util.Log;

import com.hdsx.abatis.dao.DBParser;
import com.hdsx.abatis.dao.SqlHelper;
import com.hdsx.abatis.lang.ReflectUtil;

/**
 * The Class DefaultSqlHelper.
 * 
 */
public class DefaultSqlHelper implements SqlHelper {

	/** The db connection. */
	private DBConnection dbConnection;

	/** The log tag. */
	private String logTag = "DefaultSqlHelper";

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.hdsx.abatis.dao.SqlHelper#parseSql(java.lang.String,
	 * java.lang.Object)
	 */
	/**
	 * Gets the values.
	 * 
	 * @param sql
	 *            the sql
	 * @param parameterNames
	 *            the parameter names
	 * @param parameter
	 *            the parameter
	 * @return the values
	 */
	private Object[] getValues(List<String> parameterNames, Object parameter) {
		if (parameterNames == null || parameterNames.size() == 0) {
			return null;
		}
		Object[] objects = new Object[parameterNames.size()];
		Object value = null;
		int i = 0;
		for (String parameterName : parameterNames) {
			if (parameter instanceof Map) {
				value = ((Map<?, ?>) parameter).get(parameterName);
			} else if (parameter instanceof Integer) {
				value = parameter;
			} else if (parameter instanceof String) {
				value = parameter;
			} else {
				value = ReflectUtil.getValue(parameterName, parameter);
			}
			objects[i] = value;
			i++;
		}
		return objects;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.hdsx.abatis.dao.SqlHelper#execSQL(java.lang.String)
	 */
	public int execSQL(String sqlId, Object parameter) {
		SqlSet sqlSet = getSqlSet(sqlId);
		if (sqlSet == null) {
			Log.e(logTag, "sql语句不存在");
			return 0;
		}
		String sql = sqlSet.getSql();
		/* 得到参数数据，如果参数类型为空,不加参数 */
		List<String> parameterNames = sqlSet.getParameterNames();
		List<String> attributeNames = sqlSet.getAttributeNames();
		Object[] parameterArray = getValues(parameterNames, parameter);
		Object[] attributeArray = getValues(attributeNames, parameter);
		if (attributeArray != null) {
			sql=MessageFormat.format(sql, attributeArray);
		}
		dbConnection.open();
		try {
			dbConnection.execSQL(sql, parameterArray);
		} catch (jsqlite.Exception e) {
			return 0;
		}
		return 1;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.hdsx.abatis.dao.SqlHelper#rawQuery(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> rawQuery(String sqlId, Object parameter, String type) {
		SqlSet sqlSet = getSqlSet(sqlId);
		if (sqlSet == null) {
			Log.e(logTag, "sql语句不存在");
			return null;
		}

		String sql = sqlSet.getSql();
		/* 得到参数数据，如果参数类型为空,不加参数 */
		List<String> parameterNames =sqlSet.getParameterNames()==null?null:new ArrayList<String>(sqlSet.getParameterNames());
		if (type.equals("page")) {
			sql += "  limit ? offset ?";
			if (parameterNames == null) {
				parameterNames = new ArrayList<String>();
			}
			parameterNames.add("limit");
			parameterNames.add("startIndex");
		}
		List<String> attributeNames = sqlSet.getAttributeNames();
		Object[] parameterArray = getValues(parameterNames, parameter);
		Object[] attributeArray = getValues(attributeNames, parameter);
		if (attributeArray != null) {
			sql=MessageFormat.format(sql, attributeArray);
		}
		dbConnection.open();
		List<T> result = null;
		Stmt stmt = null;
		try {
			stmt = dbConnection.rawQuery(sql, parameterArray);
			DBParser<?> dbParser = DBParser.getParser(sqlSet.getResultType().getName());
			result = (List<T>) dbParser.toBeanList(stmt, sqlSet.getResultType());
		} catch (SQLException e) {
			Log.e(logTag, "******************" + e.getMessage());
		} catch (ClassNotFoundException e) {
			Log.e(logTag, "返回类型    " + sqlSet.getResultType() + "类不存在");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(stmt!=null)
				{
				   stmt.close();
				}
			} catch (jsqlite.Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * Instantiates a new default sql helper.
	 * 
	 * @param dbConnection
	 *            the db connection
	 */
	public DefaultSqlHelper(DBConnection dbConnection) {
		this.dbConnection = dbConnection;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.hdsx.abatis.dao.SqlHelper#getDbConnection()
	 */
	public DBConnection getDbConnection() {
		return dbConnection;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.hdsx.abatis.dao.SqlHelper#getSqlSet(java.lang.String)
	 */
	@Override
	public SqlSet getSqlSet(String statementId) {

		return dbConnection.getConfiguration().getSqlSets().get(statementId);
	}

	@Override
	public <T> void batchExec(String sqlId, List<T> list) {
		SqlSet sqlSet = getSqlSet(sqlId);
		if (sqlSet == null) {
			Log.e(logTag, "sql语句不存在");
		}
		String sql = sqlSet.getSql();
		/* 得到参数数据，如果参数类型为空,不加参数 */
		List<String> parameterNames = sqlSet.getParameterNames();
		List<Object[]> parameterArray = new ArrayList<Object[]>();
		;
		for (T t : list) {
			parameterArray.add(getValues(parameterNames, t));
		}
		dbConnection.open();
		dbConnection.batchExec(sql, parameterArray);
	}

}